
#ifndef __plasma_hpp__
#define __plasma_hpp__

class PlasmaOctreeBuilder;
class Dynamic3;

class Plasma
{
public:
  enum etree_t {
    TREE_FULL,
    TREE_24,
    TREE_48
  };

  Plasma (etree_t tree_type);
  virtual ~Plasma ();

  void step();

  void render (const char *name, bool do_cross = true);

  void init();

protected:
  Statics statics;
  ElectroDynamics dyn;
  PField pfield;
  Scene scene;

  prec_t qmul;
  prec_t pmap_box;
  prec_t pmap_resolution;
  prec_t pmap_smooth;
  size_t stepmag;

  vect3d octree_c0, octree_c1;
  prec_t octree_resolution;
  prec_t octree_radius;

  Screen::eplane particle_plane;

  virtual void fill (PMap& pmap);

  enum { NONE, INITIAL } calibrate_type;

  prec_t bmul, emul;

private:
  void fieldupdate ();

  void render_screen (Scene& scene, Screen& screen, const std::string& name, const std::string& prefix);

  struct calibr
  {
    calibr (prec_t fmin, prec_t fmax, prec_t fadd) : fmin(fmin), fmax(fmax), fadd(fadd) { }
    calibr() { }
    prec_t fmin;
    prec_t fmax;
    prec_t fadd;
  };
  typedef std::map<std::string, calibr> calibration_t;
  calibration_t calibration;

  void calibrate (Scene& scene, const std::string& name);

  etree_t tree_type;
  PlasmaOctreeBuilder *builders[3];
  Octree trees[3];
  Dynamic3 *dyntree;

  typedef std::vector<vect3d> planes_t;
  planes_t planes;

  typedef std::vector<transf3d> symmetries_t;
  symmetries_t symm;
  symmetries_t rsymm;
};

#endif // !__plasma_hpp__

